//
//  SEHospitalizeViewController.swift
//  SmartEyeForPatient
//
//  Created by QDSG on 2021/4/2.
//

import UIKit

private let kHospitalizeHeaderDefaultHeight: CGFloat = 230 + UIScreen.navigationBarMaxY

class SEHospitalizeViewController: SEBaseViewController {
    
    private var viewModel = SEHospitalizeViewModel()
    private var inquiryViewModel = SEInquiryInfoViewModel(withLoading: true)
    
    override var preferredStatusBarStyle: UIStatusBarStyle { .lightContent }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        loadData(false)
        
        tableView.se_header = SERefreshHeader { [weak self] in self?.loadData() }
        
        viewModel.updateData = { [weak self] _ in
            self?.tableView.endHeaderRefreshing()
            self?.tableView.reloadData()
        }
        
        inquiryViewModel.updateData = { [weak self] status in
            switch status {
            case .success:
                if self?.inquiryViewModel.inGuideInquiry == false {
                    self?.pushToGuideDiagnosis()
                } else {
                    self?.pushToChatVC()
                }
            case .auth:
                self?.presentLoginViewController(selector: nil)
            case .failure:
                break
            }
        }

        viewModel.scanHospitalHandler = { status in
            switch status {
            case .success:
                self.handlerHospital()
            case .auth(let msg):
                self.presentLoginViewController(selector: nil) {
                    SEHUD.showError(message: msg)
                }
            case .failure(let msg):
                SEHUD.showError(message: msg)
            }
        }

        viewModel.scanDoctorHandler = { status in
            switch status {
            case .success:
                self.handlerDoctor()
            case .auth(let msg):
                self.presentLoginViewController(selector: nil) {
                    SEHUD.showError(message: msg)
                }
            case .failure(let msg):
                SEHUD.showError(message: msg)
            }
        }
        
        getLocation()
    }

    override func setupNavBar() {
        super.setupNavBar()
        navigationController?.setNavigationBarHidden(true, animated: true)
    }
    
    override func setupUI() {
        super.setupUI()
        view.addSubview(navBarView)
        navBarView.snp.makeConstraints { (make) in
            make.top.equalToSuperview()
            make.width.equalTo(UIScreen.screenWidth)
            make.height.equalTo(UIScreen.navigationBarMaxY)
        }
        
        view.addSubview(tableView)
        tableView.snp.makeConstraints { (make) in
            make.edges.equalToSuperview()
        }
        
        let tableHeader = UIView(frame: CGRect(x: 0, y: 0, width: view.width, height: kHospitalizeHeaderDefaultHeight))
        tableView.tableHeaderView = tableHeader
        
        tableHeader.addSubview(headerView)
        headerView.snp.makeConstraints { (make) in
            make.edges.equalToSuperview()
        }
        
        headerView.headerItemClosure = { [weak self] itemType in
            self?.pushToViewController(with: itemType)
        }
        headerView.headerAdvisoryClosure = { [weak self] in
            self?.checkCurrentlyInGuideInquiry()
        }
        headerView.searchNavView.searchBar.searchClosure = { [weak self] in
            self?.search()
        }
        headerView.searchNavView.scanClosure = { [weak self] in
            self?.scan()
        }
        
        navBarView.searchBar.searchClosure = { [weak self] in
            self?.search()
        }
        navBarView.scanClosure = { [weak self] in
            self?.scan()
        }
    }

    private func getLocation() {
        SELocationManager.shared.startlocating(self) { [weak self] (model) in
            guard let model = model else { return }
            self?.viewModel.locationRegion = model.region.isEmpty ? "重新定位" : model.region
            self?.viewModel.hospitalListViewModel.latitude = model.latitude
            self?.viewModel.hospitalListViewModel.longtitude = model.longitude
            self?.tableView.reloadData()
            self?.loadData()
        }
    }

    // MARK: - getter
    
    private lazy var tableView: UITableView = {
        let tableView = UITableView(frame: .zero, style: .grouped)
        tableView.backgroundColor = .white
        tableView.tableFooterView = UIView()
        tableView.estimatedRowHeight = 100
        tableView.rowHeight = UITableView.automaticDimension
        tableView.separatorStyle = .none
        tableView.delegate = self
        tableView.dataSource = self
        
        tableView.register(SEHospitalizeLocationCell.nibForCell(),
                           forCellReuseIdentifier: SEHospitalizeLocationCell.reuseIdentifier())
        tableView.register(SEHospitalizeServiceCell.nibForCell(),
                           forCellReuseIdentifier: SEHospitalizeServiceCell.reuseIdentifier())
        tableView.register(SEHospitalizeHeadlinesCell.nibForCell(),
                           forCellReuseIdentifier: SEHospitalizeHeadlinesCell.reuseIdentifier())
        return tableView
    }()
    
    private lazy var navBarView: SEHospitalizeNavSearchView = {
        let navBarView = SEHospitalizeNavSearchView(frame: .zero)
        navBarView.backgroundColor = Asset.main.color
        navBarView.isHidden = true
        return navBarView
    }()
    
    private lazy var headerView = UINib.loadViewFrom(SEHospitalizeHeader.self)
}

extension SEHospitalizeViewController {
    private func loadData(_ withLoading: Bool = false) {
        viewModel.withLoading = withLoading
        viewModel.requestHomeData()
    }
    
    private func checkCurrentlyInGuideInquiry() {
        inquiryViewModel.checkCurrentlyInGuideInquiry()
    }

    private func scanGetHospitalList() {
        viewModel.scanGetHospitalList()
    }

    private func scanGetDoctorDetail() {
        viewModel.scanGetDoctorDetail()
    }
}

// MARK: - action event

extension SEHospitalizeViewController {
    private func search() {
        pushToDoctorListVc(.department)
    }
    
    private func scan() {
        pushScanVc()
    }
}

// MARK: - push to controller

extension SEHospitalizeViewController {

    // MARK: - 跳转二维码扫描
    private func pushScanVc() {
        let scanVC = QRCodeScanVC()
        scanVC.handlerResult = { (jsonStr, scanFrom) in
            if let result = jsonStr {
                let str = result.components(separatedBy: "?").last
                let type = str?.components(separatedBy: "=").first
                let value = str?.components(separatedBy: "=").last
                if type == "deviceId" {
                    self.viewModel.scanHospitalViewModel.deviceId = value ?? ""
                    self.scanGetHospitalList()
                } else if type == "doctorId" {
                    self.viewModel.scanDoctorViewModel.model.id = value ?? ""
                    self.scanGetDoctorDetail()
                } else {
                    SEHUD.showError(in: nil, message: "二维码内容: \(result)", position: .center)
                }
            } else {
                SEHUD.showError(in: nil, message: "未能识别二维码", position: .center)
            }
        }
        self.navigationController?.pushViewController(scanVC, animated: true)
    }

    // MARK: - 跳转检查预约/检查医院列表
    private func handlerHospital() {
        if viewModel.scanHospitalViewModel.models.count == 1 {
            pushToExamineReserveVc()
        } else {
            SEHUD.showError(message: "未查询到医院，请选择!")
            pushToHospitalListVc()
        }
    }
    /// 预约检查
    private func pushToExamineReserveVc() {
        let vc = SEExamineReserveViewController(with: viewModel.scanHospitalViewModel.models[0], checkSource: 1)
        navigationController?.pushViewController(vc, animated: true)
    }

    /// 检查医院列表
    private func pushToHospitalListVc() {
        let vc = SEHospitalListViewController(with: .examine)
        navigationController?.pushViewController(vc, animated: true)
    }

    // MARK: - 跳转医生列表/医生详情
    private func handlerDoctor() {
        pushToDoctorDetailVc()
    }

    private func pushToDoctorDetailVc() {
        let vc = SEDoctorDetailViewController(with: viewModel.scanDoctorViewModel.model.id ?? "")
        navigationController?.pushViewController(vc, animated: true)
    }

    // MARK: - table view header 跳转逻辑
    
    private func pushToViewController(with itemType: SEHospitalizeHeaderItemType) {
        switch itemType {
        case .online: pushToDoctorListVc(.hospitalize)
        case .community:
            let examineVc = SEExamineViewController()
            navigationController?.pushViewController(examineVc, animated: true)
        case .outpatient:
            let registrationVc = SEHospitalListViewController(with: .registration)
            navigationController?.pushViewController(registrationVc, animated: true)
        }
    }
    
    private func pushToDoctorListVc(_ fromType: SEDoctorListFromType, departmentId: String = "") {
        let doctorListVc = SEDoctorListViewController(fromType: fromType, departmentId: departmentId)
        navigationController?.pushViewController(doctorListVc, animated: true)
    }
    
    // MARK: - 导诊
    
    /// 跳转导诊
    private func pushToGuideDiagnosis() {
        let guideDiagnosisVc = SEGuideDiagnosisInfoViewController()
        guideDiagnosisVc.title = "导诊-就诊信息填写"
        navigationController?.pushViewController(guideDiagnosisVc, animated: true)
    }
    
    private func pushToChatVC() {
        let chatVc = SEChatViewController(infoViewModel: inquiryViewModel)
        chatVc.title = "正在咨询"
        navigationController?.pushViewController(chatVc, animated: true)
    }
    
    // MARK: - section header 跳转逻辑
    
    private func pushToVc(for sectionType: SEHospitalizeSection) {
        switch sectionType {
        case .location: pushToHospitalList()
        case .service: pushToDepartmentList()
        case .headlines: SEHUD.show(message: "查看全部健康头条")
        default: break
        }
    }
    
    /// 跳转 科室 列表
    private func pushToDepartmentList() {
        let departmentVc = SEDepartmentListViewController()
        departmentVc.title = "全部科室"
        navigationController?.pushViewController(departmentVc, animated: true)
    }

    /// 跳转 检查医院 列表
    private func pushToHospitalList() {
        let hospitalVc = SEHospitalListViewController(with: .examine)
        navigationController?.pushViewController(hospitalVc, animated: true)
    }

    /// 跳转 检查医院 预约
    private func puthToExamineReserve() {
        let examinVc = SEExamineReserveViewController(with: viewModel.hospitalListViewModel.selectedItem, checkSource: 2)
        navigationController?.pushViewController(examinVc, animated: true)
    }
    
    /// 跳转 健康头条 web
    private func pushToHeadlinesWebVC(_ model: SEHospitalizeHeadlinesCellModel) {
        let webVc = SEWebViewController(url: model.url, title: model.title)
        navigationController?.pushViewController(webVc, animated: true)
    }
}

// MARK: - UITableViewDataSource

extension SEHospitalizeViewController: UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        return viewModel.numberOfSections
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        viewModel.numberOfRows(in: section)
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let sectionType = SEHospitalizeSection(rawValue: indexPath.section) ?? .unknown
        
        switch sectionType {
        case .location:
            let cell = tableView.dequeueReusableCell(withIdentifier: SEHospitalizeLocationCell.reuseIdentifier()) as! SEHospitalizeLocationCell
            cell.delegate = self
            cell.update(with: viewModel)
            return cell
        case .service:
            let cell = tableView.dequeueReusableCell(withIdentifier: SEHospitalizeServiceCell.reuseIdentifier()) as! SEHospitalizeServiceCell
            cell.delegate = self
            cell.update(with: viewModel)
            return cell
        case .headlines:
            let cell = tableView.dequeueReusableCell(withIdentifier: SEHospitalizeHeadlinesCell.reuseIdentifier()) as! SEHospitalizeHeadlinesCell
            cell.update(with: viewModel.headlineModel(indexPath: indexPath))
            return cell
        default:
            return UITableViewCell()
        }
    }
}

// MARK: - UITableViewDelegate

extension SEHospitalizeViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: false)
        
        let sectionType = SEHospitalizeSection(rawValue: indexPath.section) ?? .unknown
        switch sectionType {
        case .headlines:
            let model = viewModel.headlineModel(indexPath: indexPath)
            pushToHeadlinesWebVC(model)
        default:
            break
        }
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let sectionType = SEHospitalizeSection(rawValue: section) ?? .unknown
        
        let header = UINib.loadViewFrom(SEHospitalizeSectionHeader.self)
        header.updateUI(section: sectionType, btnTitle: viewModel.locationRegion) { (type) in
            self.pushToVc(for: type)
        } located: { (type) in
            self.getLocation()
        }
        return header
    }
    
    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        return UIView()
    }
    
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 50
    }
    
    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        return 8
    }
    
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if scrollView.contentOffset.y >= UIScreen.statusBarHeight {
            navBarView.isHidden = false
            view.insertSubview(navBarView, aboveSubview: tableView)
        } else {
            navBarView.isHidden = true
            navBarView.removeFromSuperview()
        }
    }
}

extension SEHospitalizeViewController: SEHospitalizeServiceCellDelegate, SEHospitalizeLocationCellDelegate {
    func hospitalizeServiceCell(_ cell: SEHospitalizeServiceCell, didSeleectedWith departmentId: String) {
        pushToDoctorListVc(.department, departmentId: departmentId)
    }
    
    func hospitalizeLocationCell(_ cell: SEHospitalizeLocationCell, didSelectRowAt indexPath: IndexPath) {
        let hospitalItem = viewModel.hospitalListViewModel.listItem(indexPath: indexPath)
        viewModel.hospitalListViewModel.selectedItem = hospitalItem
        puthToExamineReserve()
    }
}
